/********************************************
 * 功能说明: 
 * 模块名称: 
 * 系统名称: 
 * 软件版权: 
 * 系统版本: 1.0.0
 * 开发人员: zhangfb
 * 开发时间: 2019/3/29 22:42
 * 审核人员: 
 * 相关文档: 
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.hyacinth.batch;

import com.hyacinth.batch.exception.BatException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 批量基础JOB类
 * @author zhangfb
 * @version 1.0.0.1
 * @since JDK 1.8
 */
public abstract class BaseBatchJob {

    private static final Logger LOGGER = LoggerFactory.getLogger(BaseBatchJob.class);

    /**
     * 任务运行状态
     */
    private boolean isRunning = false;

    /**
     * 任务调用
     */
    public void action() {
        // 启动
        LOGGER.error("{}-{}|{}任务启动执行", Thread.currentThread().getId(), System.currentTimeMillis(), getJobName());
        if (!startRun()) {
            return;
        }
        try {
            // 初始化
            init();
            // 前置执行
            before();
            // 执行
            execute();
            // 后置执行
            after();
        } catch (BatException e) {
            LOGGER.error("{}任务执行批量异常", getJobName(), e);
        } catch (Exception e) {
            LOGGER.error("{}计划任务出错", getJobName(), e);
        } finally {
            // 结束
            stopRun();
            LOGGER.error("{}-{}|{}任务结束执行", Thread.currentThread().getId(), System.currentTimeMillis(), getJobName());
        }
    }

    /**
     * 获取Job名称
     * @return Job名称
     */
    private String getJobName() {
        return this.getClass().getSimpleName();
    }

    /**
     * 开始执行
     * 并发情况，只允许一个线程进入
     */
    private synchronized boolean startRun() {
        // 校验任务是否启动
        if (isRunning) {
            LOGGER.info("{}任务执行中……", getJobName());
            return false;
        }
        isRunning = true;
        return true;
    }

    /**
     * 终止执行
     * 此处可以不考虑并发，因为启动时已有控制
     */
    private void stopRun() {
        isRunning = false;
    }

    /** 任务初始化操作 **/
    protected abstract void init() throws BatException;
    /** 任务执行 **/
    protected abstract void before() throws BatException;
    /** 任务执行 **/
    protected abstract void execute() throws BatException, InterruptedException;
    /** 任务执行 **/
    protected abstract void after() throws BatException;
}
